package core;

import java.awt.image.BufferedImage;
import java.util.ArrayList;

import common.Def;

import filter.*;

public class Worklet{
	// RT properties
	private int period;
	private int wcet;
	
	// progress
	private int progress_clk_in_period;
	private int progress_clk_in_work;
	
	// timestamps
	private long ts_requested;
	private long ts_ready_q;
	private long ts_done;
	
	// resource related
	private int type;
	private String name;
	private Raster image;
	private int cp;
	
	// operator holder
	private ArrayList<Integer> requests = null;
	private FilterModule filter = null;
	
	// owner
	private int request_pid;
	private long request_ip;
	
	public Worklet( Resource _src, ArrayList<Integer> _requests, int _pid, long _ip ){
		type = _src.getType();
		name = _src.get_filename();
		
		// pixel convert
		image = new Raster( _src.get_image() );
		
		// orders
		requests = _requests;
		
		// priority
		wcet = ( int )( Math.random() * 9 + 1 );
		period = ( int )( wcet * ( Math.random() * 8 + 2 ) );
		progress_clk_in_period = 0;
		progress_clk_in_work = 0;
		
		// timestamp
		ts_requested = System.currentTimeMillis();
		
		// owner
		request_pid = _pid;
		request_ip = _ip;
	}
	
	public boolean exec(){
		// load filter
		if( filter == null ){
			System.out.println( "new filter" );
			filter = next_filter();
			cp = 0;
		}
		
		// exec
		boolean subtask_left = filter.exec( image, cp, Def.ALLOWANCE );

		// progress
		progress_clk_in_work++;
		cp += Def.ALLOWANCE;
		
		// if a subtask is done
		if( subtask_left ){
			// done a filter
			name = filter.get_name() + "(" + name + ")";
			filter = null;
			
			System.out.println( "DONE: partial" );
			
			if( requests.isEmpty() ){
				// done all subtasks
				System.out.println( "DONE: " + name );
				return true;
			}
		}
		
		return false;
	}
	
	public boolean update(){
		boolean deadline_met = true;
		
		if( ++progress_clk_in_period >= period ){
			// deadline
			if( progress_clk_in_work < wcet ){
				// ** !! deadline miss !! **
				System.err.println( "-worklet: DEADLINE MISS!!" );
				deadline_met = false;
			}
			
			progress_clk_in_period = 0;
			progress_clk_in_work = 0;
		}
		
		return deadline_met;
	}
	
	public boolean ready(){
		return ( progress_clk_in_work < wcet );
	}
	
	// accessors
	public String get_name(){ return name; }
	public BufferedImage get_image(){
		return image.get_image( type );
	}
	public int get_period(){ return period; }
	public int get_wcet(){ return wcet; }
	public double get_wcet_over_period(){ return wcet / ( double )period; }
	public long get_ts_request(){ return ts_requested; }
	public long get_ts_ready(){ return ts_ready_q; }
	public long get_ts_done(){ return ts_done; }
	public long get_request_ip(){ return request_ip; }
	public int get_request_pid(){ return request_pid; }
	
	public void set_ts_ready( long ts ){ ts_ready_q = ts; }
	public void set_ts_done( long ts ){ ts_done = ts; }
		
	private FilterModule next_filter(){
		if( requests == null || requests.isEmpty() ) return null;
		
		switch( requests.remove( 0 ) ){
			case FilterModuleList.GRAYSCALE:
				return new Grayscaler();
				
			case FilterModuleList.BINARIZE:
				return new Binarizer();
				
			case FilterModuleList.BLUR:
				return new Blurrer();
				
			case FilterModuleList.GBLUR:
				return new Gaussian();
				
			default:
				return null;
		}
	}
}
